﻿/*
 * magic.hpp
 *
 *  Created on: 2023年5月8日
 *      Author: Dylan.Gao
 */

#ifndef _DM_MAGIC_HPP_
#define _DM_MAGIC_HPP_

#include <dm/types.hpp>

namespace dm{

/**
 * 魔数
 * 魔数具有两种状态：无效和有效
 * 有效状态时，魔数值会随着调用刷新而变化，代表本魔数已经更新。
 */
class CMagic{
public:
	/**
	 * 魔数存储类型
	 */
	typedef uint64 magic_t;
	static const magic_t MaskData = 0x000000FF;
	static const magic_t MaskZero = 0xFF00FF00;

	CMagic( volatile magic_t* shared ):m_shared(shared){
		if( m_shared )
			m_local = *m_shared;
	}

	CMagic& operator=( const CMagic& magic ){
		m_shared = magic.m_shared;
		if( m_shared )
			m_local = *m_shared;
		return *this;
	}

	CMagic& operator=( volatile magic_t* shared ){
		m_shared = shared;
		if( m_shared )
			m_local = *m_shared;

		return *this;
	}

	inline void init(){
		if( m_shared ){
			m_local = MaskZero;
			*m_shared = m_local;
		}
	}

	/**
	 * 魔数是否有效
	 * @return
	 */
	inline bool ifValid()const{
		if( MaskZero!=(m_local&MaskZero) )	// 0区不为0
			return false;

		if( (m_local&MaskData) != (m_local>>16&MaskData) )	// 数据区不一致
			return false;

		return true;
	}

	/**
	 * 销毁魔数区寄存器
	 */
	inline void destroy(){
		if( m_shared ){
			m_local = 0;
			*m_shared = m_local;
		}
	}

	/**
	 * 更新本地魔数
	 */
	inline bool update(){
		if( m_shared ){
			if( !ifUpdated() ){
				m_local = *m_shared;
				return true;
			}
		}
		return false;
	}

	/**
	 * 是否为最新
	 * @return
	 */
	inline bool ifUpdated(){
		return (m_shared && m_local==(*m_shared));
	}

	inline void refresh(){
		if( m_shared ){
			++m_local;
			m_local &= 0x000000FF;
			m_local |= m_local<<16;
			m_local |= MaskZero;
			*m_shared = m_local;
		}
	}

	inline const magic_t& local()const{
		return m_local;
	}

	inline magic_t shared()const{
		if( m_shared )
			return *m_shared;
		return 0;
	}
private:
	/**
	 * 本地数值
	 */
	magic_t m_local;

	/**
	 * 共享数值指针
	 */
	volatile magic_t* m_shared;
};

}

#endif /* _DM_MAGIC_HPP_ */
